package com.demo.shiro.config;

import com.demo.shiro.mapper.RolePermissionMapper;
import com.demo.shiro.mapper.UserRoleMapper;
import com.demo.shiro.model.Permission;
import com.demo.shiro.model.Role;
import org.apache.commons.lang3.StringUtils;
import com.demo.shiro.model.UserInfo;
import com.demo.shiro.service.UserInfoService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author Jmy
 * @date 2019/7/25 13:15
 * @email jiaomingyu5778@gmail.com
 */
public class ShiroRealm extends AuthorizingRealm {

    private static final String USER_ACCOUNT_STATUS = "0";

    private static final Logger logger = LoggerFactory.getLogger(ShiroRealm.class);

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    /**
     * 获取用户角色和权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        String userName = (String) SecurityUtils.getSubject().getPrincipal();

        logger.info("用户" + userName + "获取权限---ShiroRealm.doGetAuthorizationInfo");

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        // 获取用户角色集
        List<Role> roleList = userRoleMapper.findByUserName(userName);
        Set<String> roleSet = new HashSet<>();
        for (Role r : roleList) {
            roleSet.add(r.getName());
        }
        simpleAuthorizationInfo.setRoles(roleSet);

        // 获取用户权限集
        List<Permission> permissionList = rolePermissionMapper.findByUserName(userName);
        Set<String> permissionSet = new HashSet<>();

        for (int i = 0; i < permissionList.size(); i++) {
            if (null == permissionList.get(i)) {
                continue;
            }
            permissionSet.add(permissionList.get(i).getName());
        }
        simpleAuthorizationInfo.setStringPermissions(permissionSet);

        return simpleAuthorizationInfo;
    }

    /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String userName = (String) token.getPrincipal();
        String passWord = new String((char[])token.getCredentials());

        logger.info("登录认证,用户密码：" + userName + ":" + passWord);

        UserInfo userInfo = this.userInfoService.findByUserName(userName);

        if (userInfo == null) {
            throw new UnknownAccountException("用户名或密码错误！");
        }

        if (!StringUtils.equals(passWord, userInfo.getPassword())) {
            throw new IncorrectCredentialsException("用户名或密码错误！");
        }

        if (StringUtils.equals(userInfo.getStatus(), USER_ACCOUNT_STATUS)) {
            throw new LockedAccountException("账号已被锁定,请联系管理员！");
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userName, passWord, getName());

        return info;
    }
}
